1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include <cstdio> #include <queue> #define LL long long const int maxn = 5e5 + 5; using namespace std; struct T{ struct A{ int son[2], v, tim; A(){ tim = -1; v = 0; } }a[maxn * 50]; int tot = 0; void insert(int u, int v, LL x, int dep, int tim){ a[v] = a[u]; a[v].v++; if (dep < 0){ a[v].tim = tim; return; } int d = (x >> (1ll * dep)) & 1ll; insert(a[u].son[d], a[v].son[d] = ++tot, x, dep - 1, tim); } int find(int u, int v, int dep, LL x){ if (dep < 0) return a[v].tim; int d = (x >> (1ll * dep)) & 1ll; if (a[a[v].son[d ^ 1]].v - a[a[u].son[d ^ 1]].v != 0) return find(a[u].son[d ^ 1], a[v].son[d ^ 1], dep - 1, x); return find(a[u].son[d], a[v].son[d], dep - 1, x); } }t; int rt[maxn]; int n, k; LL a[maxn]; struct A{ int s, l, r, pos; bool operator<(A x)const{ return (a[s] ^ a[pos]) < (a[x.s] ^ a[x.pos]); } }; priority_queue <A> q; signed main(){
scanf("%d%d", &n, &k); t.insert(0, rt[0] = ++t.tot, 0, 32, 0); for (int i = 1; i <= n; i++){ scanf("%lld", a + i); a[i] ^= a[i - 1]; t.insert(rt[i - 1], rt[i] = ++t.tot, a[i], 32, i); } LL res = 0; for (int i = 1; i <= n; i++) q.push(A{i - 1, i, n, t.find(rt[i - 1], rt[n], 32, a[i - 1])}); while (k--){ A now = q.top(); q.pop(); res += (a[now.s] ^ a[now.pos]); if (now.l < now.pos) q.push(A{now.s, now.l, now.pos - 1, t.find(rt[now.l - 1], rt[now.pos - 1], 32, a[now.s])}); if (now.pos < now.r) q.push(A{now.s, now.pos + 1, now.r, t.find(rt[now.pos], rt[now.r], 32, a[now.s])}); } printf("%lld\n", res); return 0; }
|